package service

import (
	"hrms-api/model"
	"time"

	"gorm.io/gorm"
)

// SalaryService 薪资服务
type SalaryService struct {
	DB *gorm.DB
}

// NewSalaryService 创建薪资服务
func NewSalaryService(db *gorm.DB) *SalaryService {
	return &SalaryService{DB: db}
}

// CreateSalary 创建薪资记录
func (s *SalaryService) CreateSalary(userID uint, year int, month int, baseSalary, bonus, overtime, allowance, deduction, tax, insurance, fund, netSalary float64, paymentDate time.Time, status int, remark string) (*model.Salary, error) {
	// 检查用户是否存在
	var user model.User
	if err := s.DB.First(&user, userID).Error; err != nil {
		return nil, err
	}

	// 检查是否已存在该月薪资记录
	var existingSalary model.Salary
	result := s.DB.Where("user_id = ? AND year = ? AND month = ?", userID, year, month).First(&existingSalary)
	if result.Error != gorm.ErrRecordNotFound {
		return nil, result.Error
	}

	// 创建薪资记录
	salary := model.Salary{
		UserID:      userID,
		Year:        year,
		Month:       month,
		BaseSalary:  baseSalary,
		Bonus:       bonus,
		Overtime:    overtime,
		Allowance:   allowance,
		Deduction:   deduction,
		Tax:         tax,
		Insurance:   insurance,
		Fund:        fund,
		NetSalary:   netSalary,
		PaymentDate: paymentDate,
		Status:      status,
		Remark:      remark,
	}

	if err := s.DB.Create(&salary).Error; err != nil {
		return nil, err
	}

	return &salary, nil
}

// UpdateSalary 更新薪资记录
func (s *SalaryService) UpdateSalary(salaryID string, baseSalary, bonus, overtime, allowance, deduction, tax, insurance, fund, netSalary float64, paymentDate time.Time, status int, remark string) (*model.Salary, error) {
	var salary model.Salary
	if err := s.DB.First(&salary, salaryID).Error; err != nil {
		return nil, err
	}

	// 更新薪资信息
	updates := map[string]interface{}{
		"base_salary":  baseSalary,
		"bonus":        bonus,
		"overtime":     overtime,
		"allowance":    allowance,
		"deduction":    deduction,
		"tax":          tax,
		"insurance":    insurance,
		"fund":         fund,
		"net_salary":   netSalary,
		"payment_date": paymentDate,
		"status":       status,
		"remark":       remark,
	}

	if err := s.DB.Model(&salary).Updates(updates).Error; err != nil {
		return nil, err
	}

	return &salary, nil
}

// GetSalary 获取薪资记录
func (s *SalaryService) GetSalary(salaryID string) (*model.Salary, error) {
	var salary model.Salary
	result := s.DB.Preload("User").First(&salary, salaryID)
	if result.Error != nil {
		return nil, result.Error
	}
	return &salary, nil
}

// ListSalaries 获取薪资记录列表
func (s *SalaryService) ListSalaries(userID, year, month, status string) ([]model.Salary, error) {
	db := s.DB.Preload("User")

	// 根据用户ID筛选
	if userID != "" {
		db = db.Where("user_id = ?", userID)
	}

	// 根据年份筛选
	if year != "" {
		db = db.Where("year = ?", year)
	}

	// 根据月份筛选
	if month != "" {
		db = db.Where("month = ?", month)
	}

	// 根据状态筛选
	if status != "" {
		db = db.Where("status = ?", status)
	}

	var salaries []model.Salary
	if err := db.Find(&salaries).Error; err != nil {
		return nil, err
	}

	return salaries, nil
}

// GetSalaryHistory 获取薪资历史记录
func (s *SalaryService) GetSalaryHistory(userID uint, startYear, startMonth, endYear, endMonth string) ([]model.Salary, error) {
	db := s.DB.Where("user_id = ?", userID)

	// 添加时间范围筛选
	if startYear != "" && startMonth != "" {
		db = db.Where("(year > ? OR (year = ? AND month >= ?))", startYear, startYear, startMonth)
	}
	if endYear != "" && endMonth != "" {
		db = db.Where("(year < ? OR (year = ? AND month <= ?))", endYear, endYear, endMonth)
	}

	// 按时间倒序排序
	db = db.Order("year DESC, month DESC")

	var salaries []model.Salary
	if err := db.Find(&salaries).Error; err != nil {
		return nil, err
	}

	return salaries, nil
}

// CalculateSalary 计算薪资
func (s *SalaryService) CalculateSalary(userID uint, year int, month int) (*model.Salary, error) {
	// 获取员工信息
	var employee model.Employee
	if err := s.DB.Where("user_id = ?", userID).First(&employee).Error; err != nil {
		return nil, err
	}

	// 获取当月考勤记录
	var attendances []model.Attendance
	if err := s.DB.Where("user_id = ? AND YEAR(date) = ? AND MONTH(date) = ?", userID, year, month).Find(&attendances).Error; err != nil {
		return nil, err
	}

	// 计算基础薪资
	baseSalary := employee.BaseSalary

	// 计算加班工资
	overtime := 0.0
	for _, attendance := range attendances {
		if attendance.Status == 1 || attendance.Status == 2 {
			overtime += attendance.CheckOut.Sub(attendance.CheckIn).Hours() - 8
		}
	}
	overtimePay := overtime * employee.OvertimeRate

	// 计算请假扣款
	leaveDeduction := 0.0
	for _, attendance := range attendances {
		if attendance.Status == 5 {
			leaveDeduction += float64(attendance.LeaveTime) * employee.DailySalary / 8
		}
	}

	// 计算社保公积金
	insurance := baseSalary * employee.InsuranceRate
	fund := baseSalary * employee.FundRate

	// 计算税前薪资
	grossSalary := baseSalary + overtimePay - leaveDeduction

	// 计算个人所得税
	tax := calculateTax(grossSalary - insurance - fund)

	// 计算实发薪资
	netSalary := grossSalary - insurance - fund - tax

	// 返回计算结果
	return &model.Salary{
		UserID:     userID,
		Year:       year,
		Month:      month,
		BaseSalary: baseSalary,
		Overtime:   overtimePay,
		Allowance:  employee.Allowance,
		Deduction:  leaveDeduction,
		Insurance:  insurance,
		Fund:       fund,
		Tax:        tax,
		NetSalary:  netSalary,
	}, nil
}

// calculateTax 计算个人所得税
func calculateTax(income float64) float64 {
	if income <= 5000 {
		return 0
	} else if income <= 8000 {
		return (income - 5000) * 0.03
	} else if income <= 17000 {
		return (income-8000)*0.1 + 90
	} else if income <= 30000 {
		return (income-17000)*0.2 + 990
	} else if income <= 40000 {
		return (income-30000)*0.25 + 3590
	} else if income <= 60000 {
		return (income-40000)*0.3 + 6090
	} else if income <= 85000 {
		return (income-60000)*0.35 + 12090
	} else {
		return (income-85000)*0.45 + 20840
	}
}
